<?
//----------------------------------------------------------------------------------------
//  LAST UPDATA 2005.07.11
//  +   add: set and set_expressions in SQL UPDATE
//  +   add: function ExecuteQueryWithLoad($query)
//----------------------------------------------------------------------------------------
class BusinessObject{
  var $fields = array();
  var $values = array();

  var $leftJoined = array();
  var $innerJoined = array();
  var $relations = array();
  var $select_expressions = array();
  var $set_expressions = array();
  var $attached_values = array();

  var $select_all = true;
  var $row;
  var $tableName;
  var $db;
  var $subQuery = "";
  var $COLLATE = "";
  var $CALCULATE_FIELDS = "";
  var $last_query = "";

//-----------------------------------------PUBLIC PART ---------------------------------

 /* Constructor */
  function BusinessObject($tableName){
    global $db;
    $this->db = &$db;
    $this->tableName = $tableName;
  }

  /*  ExecuteQuery  */
  function ExecuteQuery($query){
    if(DEBUG){print("\n<br>".$query);}
    $this->last_query = $query;
    return ($this->db->query($query));
  }

  /*  Insert  */
  function Insert(){
    $k="";$v="";
    foreach($this->fields as $key=>$val){
      if(isset($this->values[$val])){
        if($k){
          $k.=",";
          $v.=",";
        }
        $k.="`{$this->fields[$key]}`";
        $v.="'".addslashes($this->values[$val])."'";
      }
    }
    return(($k)&&($v)&&$this->ExecuteQuery("INSERT INTO {$this->tableName} ($k) VALUES ($v)"));
  }

  /*  getInsertID */
  function getInsertID(){
    return(mysql_insert_id());
  }

  function getMaxField($fieldName)
  {
    $n = 0;
    $query = "SELECT MAX(".$fieldName.") as n FROM {$this->tableName}";
    if($this->data = ($this->ExecuteQuery($query)))
    {
      if($row = mysql_fetch_array($this->data))
      {
        $n = $row[0];
      }
    }
    return $n;
  }

  function getMinField($fieldName)
  {
    $n = 0;
    $query = "SELECT MIN(".$fieldName.") as n FROM {$this->tableName}";
    if($this->data = ($this->ExecuteQuery($query)))
    {
      if($row = mysql_fetch_array($this->data))
      {
        $n = $row[0];
      }
    }
    return $n;
  }

  /*  Update */
  function Update($where){
    $s=$this->getSetStatement();
    return($s&&$this->ExecuteQuery("UPDATE {$this->tableName} SET $s WHERE $where"));
  }

  /*  Delete  LAST UPDATE 2004.11.12 17:50 */
  function Delete($isAll = true,$where=""){
    if(!$isAll){
      $limit=" LIMIT 1";
    } else {
    	$limit="";
    }
    return($this->ExecuteQuery("DELETE FROM {$this->tableName} ".$this->getWhere($where).$limit));
  }

  /*  Load  */
  function Load($offset=0,$rows=0,$order="",$where="",$group=""){
    if($group){
      $group= " GROUP BY {$this->tableName}.$group";
    }
		$limit=' ';
    if($rows!=0&&$rows!="0"){
      $limit=" LIMIT $offset,$rows";
    }
    return($this->data = $this->ExecuteQuery($this->getSelectStatement()." FROM {$this->subQuery} {$this->tableName} ".$this->getInnerJoin().$this->getLeftJoin().$this->getWhere($where).$group.$this->getOrder($order).$limit));
  }

  /*  FullLoad 2004.12.17 */
  function FullLoad($index="",$offset=0,$rows=0,$order="",$where="",$group=""){
    $this->Load($offset,$rows,$order,$where,$group);
    foreach($this->fields as $key => $val){
      $this->values[$val] = array();
    }
    for($i=0;$row = mysql_fetch_array($this->data);$i++){
      if($index){
        $this->getFullNextForJoin($row,$row[$this->fields[$index]]);
      } else {
        $this->getFullNextForJoin($row,$i);
      }
    }
  }

  /**/
  function getRowsCount()
  {
    if($this->data)
    {
      return $this->db->rows_count($this->data);
    }else
    {
      return 0;
    }
  }

  /*  getCount  */
  function getCount($where="",$group=""){
    if($group!=""){
      $group= " GROUP BY {$this->tableName}.$group";
    }
    $query = "SELECT COUNT(*) as 'count' FROM {$this->subQuery} {$this->tableName} ".$this->getLeftJoin().$this->getWhere($where).$group." LIMIT 0,1";
    if($this->data = ($this->ExecuteQuery($query))){
      if($row = mysql_fetch_array($this->data)){
        return($row[0]);
      }
    }
    return(0);
  }
  /*  Next  */
  function Next(){
	// Warning: mysql_fetch_array(): 29 is not a valid MySQL result resource in /home/dnipro/public_html/classes/business/BusinessObject.class.php on line 103
    if(!($this->row = mysql_fetch_array($this->data))){
      return(false);
    }
    ///print("\n---------------".get_class($this)."-----------------------\n");
    ///var_dump($row);
    $this->getNextForJoin($this->row);
    return($this->values);
  }
  /*  leftJoin */
  function leftJoin(&$bo){
  	$this->leftJoined[get_class($bo)] = &$bo;
  }
  /*  innerJoin */
  function innerJoin(&$bo){
  	$this->innerJoined[get_class($bo)] = &$bo;
  }

  /* function 'select' add <select_expression> in <select_statement>
   * select_expression := <table_field> or <select_function> or <select_subquery>
   * Example of select_expression: 'users';
   *                               COUNT(*) as count;
   *                               (SELECT COUNT(*) as users FROM users WHERE ...)
   *
   * Example of usage:  $bo->select($bo->fields[users]);
   *                    $bo->select('COUNT(*) as count');
  */
  function select($select_expression){
  	array_push($this->select_expressions,$select_expression);
  }

  function set($set_expression){
  	array_push($this->set_expressions,$set_expression);
  }

  function attachValues(){
    array_push($this->attached_values,$this->values);
  }

//-----------------------------------------PRIVATE PART ---------------------------------

  /*  getFields */
  function getFields(){
    $s="";
    foreach($this->fields as $key=>$val){
      if(isset($this->values[$val])){
       	$v="";
    		if(is_array($this->values[$val])){
          $v=implode(",",$this->values[$val]);
    		  if($v)
    			 $v=" {$this->tableName}.$val IN($v)";
    		}else{
    		  $v= " {$this->tableName}.$val = '".addslashes($this->values[$val])."'";
    		}
        if($s)
          $s.=" AND ";
        $s.= $v;
      }
    }
    foreach($this->leftJoined as $key =>$val){
      $f= $this->leftJoined[$key]->getFields();
      $s = ($f&&$s)?("$s AND $f"):(($s)?$s:$f);
    }
    foreach($this->innerJoined as $key =>$val){
      $f= $this->innerJoined[$key]->getFields();
      $s = ($f&&$s)?("$s AND $f"):(($s)?$s:$f);
    }
    return($s);
  }
  /*  setAttributes */
  function setAttributes(){
    foreach($this->fields as $key =>$val){
      $this->$key =&$this->values[$this->fields[$key]];
    }
  }

  /* getWhere */
  function getWhere($where=""){
    $result = $this->getFields();
    return(($result!="")?(" WHERE $result ".(($where!="")?" AND ($where) ":"")):(($where!="")?" WHERE $where ":""));
  }

  /*  getOrder  */
  function getOrder($order){
    if($order!=""){
			$s="";
      foreach($order as $key =>$val){
        $f=" $key ".(($val=="1"||$val=="DESC")? $this->COLLATE." DESC": $this->COLLATE." ASC");
        $s = ($f&&$s)?("$s,$f"):(($s)?$s:$f);
      }
      return(" ORDER BY $s ");
    }
    return(" ");
  }

  /* getLeftJoin */
  function getLeftJoin(){
    $result = "";
    foreach($this->leftJoined as $bo){
      if (isset($this->relations[$bo->tableName])) {
        $result.=" LEFT JOIN {$bo->tableName} ON {$this->relations[$bo->tableName]} ".$bo->getLeftJoin();
      } else if (isset($bo->relations[$this->tableName])) {
        $result.=" LEFT JOIN {$bo->tableName} ON {$bo->relations[$this->tableName]} ".$bo->getLeftJoin();
      }
    }
    return($result);
  }
  /* getInnerJoin */
  function getInnerJoin(){
    $result = "";
    foreach($this->innerJoined as $bo){
      if (isset($this->relations[$bo->tableName])) {
        $result.=" INNER JOIN {$bo->tableName} ON {$this->relations[$bo->tableName]} ".$bo->getInnerJoin();
      } else if (isset($bo->relations[$this->tableName])) {
        $result.=" INNER JOIN {$bo->tableName} ON {$bo->relations[$this->tableName]} ".$bo->getInnerJoin();
      }
    }
    return($result);
  }

  /* function private   */
  function getSetStatement(){
    $s = implode(",",$this->set_expressions);
    foreach($this->fields as $key => $val){
      if(isset($this->values[$val])){
        $f="{$this->fields[$key]} = '".addslashes($this->values[$val])."'";
        $s = ($f&&$s)?("$s,$f"):(($s)?$s:$f);
      }
    }
    return($s);
  }

  /* function 'getNextForJoin' copy parts from array values to special join variables*/
  function getNextForJoin(&$row){
    foreach($this->fields as $val){
      $this->values[$val]= stripslashes($row[$val]);
//      $this->values[$val]=&$row[$val];
    }
    foreach($this->leftJoined as $key => $val){
      $this->leftJoined[$key]->getNextForJoin($row);
    }
    foreach($this->innerJoined as $key => $val){
      $this->innerJoined[$key]->getNextForJoin($row);
    }
  }
  /* function 'getNextForJoin' copy parts from array values to special join variables*/
  function getFullNextForJoin(&$row,$key){
    foreach($this->fields as $val){
      $this->values[$val][$key] = stripslashes($row[$val]);
    }
    foreach($this->leftJoined as $key => $val){
      $this->leftJoined[$key]->getFullNextForJoin($row);
    }
    foreach($this->innerJoined as $key => $val){
      $this->innerJoined[$key]->getFullNextForJoin($row);
    }
  }

  /* function private getSelectForJoin*/
  function getSelectForJoin(){
    reset($this->select_expressions);
		$s="";
    foreach($this->select_expressions as $key => $val){
      $f = $this->select_expressions[$key];
      $s = ($f&&$s)?("$s,$f"):(($s)?$s:$f);
    }
    foreach($this->leftJoined as $key =>$val){
      $f = $this->leftJoined[$key]->getSelectForJoin();
      $s = ($f&&$s)?("$s,$f"):(($s)?$s:$f);
    }
    return($s);
  }

  /* function private getSelectStatement*/
  function getSelectStatement(){
    $result = $this->getSelectForJoin();
    if ($this->select_all)
    	return("SELECT * ".$this->CALCULATE_FIELDS." ".(($result)?",$result":""));
    else
    	return("SELECT ".$this->CALCULATE_FIELDS." ".(($result)?",$result":""));
  }

  function ExecuteQueryWithLoad($query) {
	return ($this->data = $this->ExecuteQuery($query));
  }

  function num_rows() {
    return mysql_num_rows($this->data);
  }

}
?>
